using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Terra.Core.Common.ApiResponse;
using Terra.Core.Common.ErrorCodes.Constants;
using Terra.Core.Common.Exceptions;
using Terra.Core.Common.Models.Pagination;
using Terra.Data.Entities.Identity;
using Terra.Data.Models.Identity;
using Terra.Service.Identity.Interfaces;

namespace Terra.WebApi.Areas.Admin.Controllers;

/// <summary>
/// 角色管理控制器
/// </summary>
/// <remarks>
/// 提供以下功能：
/// <list type="bullet">
/// <item><description>角色查询</description></item>
/// <item><description>角色详情</description></item>
/// <item><description>角色创建</description></item>
/// <item><description>角色更新</description></item>
/// <item><description>角色删除</description></item>
/// <item><description>批量删除角色</description></item>
/// <item><description>角色用户分配</description></item>
/// <item><description>角色用户移除</description></item>
/// </list>
/// </remarks>
[Area("Admin")]
[ApiController]
[Route("api/admin/roles")]
[ApiExplorerSettings(GroupName = "v1-admin")]
[Authorize]
public class RoleController : ControllerBase
{
    private readonly IRoleService _roleService;
    private readonly ILogger<RoleController> _logger;

    /// <summary>
    /// 构造函数
    /// </summary>
    /// <param name="roleService">角色服务</param>
    /// <param name="logger">日志记录器</param>
    public RoleController(
        IRoleService roleService,
        ILogger<RoleController> logger)
    {
        _roleService = roleService ?? throw new ArgumentNullException(nameof(roleService));
        _logger = logger ?? throw new ArgumentNullException(nameof(logger));
    }

    /// <summary>
    /// 获取该控制器的API文档
    /// </summary>
    /// <returns>API文档</returns>
    [HttpGet("api-docs")]
    [ApiExplorerSettings(IgnoreApi = true)]
    public IActionResult GetApiDocs()
    {
        var docs = new
        {
            Controller = "角色管理",
            Description = "提供角色相关的CRUD操作和角色用户分配功能",
            Version = "v1",
            Endpoints = new[]
            {
                new
                {
                    Path = "/api/admin/roles",
                    Method = "GET",
                    Description = "分页查询角色",
                    Parameters = "查询条件(RoleQueryDto)"
                },
                new
                {
                    Path = "/api/admin/roles/{id}",
                    Method = "GET",
                    Description = "获取角色详情",
                    Parameters = "角色ID(Guid)"
                },
                new
                {
                    Path = "/api/admin/roles/select",
                    Method = "GET",
                    Description = "获取角色选择列表",
                    Parameters = "无"
                },
                new
                {
                    Path = "/api/admin/roles",
                    Method = "POST",
                    Description = "创建角色",
                    Parameters = "角色创建信息(RoleCreateDto)"
                },
                new
                {
                    Path = "/api/admin/roles/{id}",
                    Method = "PUT",
                    Description = "更新角色",
                    Parameters = "角色ID(Guid), 角色更新信息(RoleUpdateDto)"
                },
                new
                {
                    Path = "/api/admin/roles/{id}",
                    Method = "DELETE",
                    Description = "删除角色",
                    Parameters = "角色ID(Guid)"
                },
                new
                {
                    Path = "/api/admin/roles/batch-delete",
                    Method = "POST",
                    Description = "批量删除角色",
                    Parameters = "角色ID列表(RoleBatchDeleteDto)"
                },
                new
                {
                    Path = "/api/admin/roles/{roleId}/users",
                    Method = "GET",
                    Description = "获取角色用户列表",
                    Parameters = "角色ID(Guid)"
                },
                new
                {
                    Path = "/api/admin/roles/assign-users",
                    Method = "POST",
                    Description = "为角色分配用户",
                    Parameters = "分配参数(RoleAssignUsersDto)"
                },
                new
                {
                    Path = "/api/admin/roles/remove-users",
                    Method = "POST",
                    Description = "从角色中移除用户",
                    Parameters = "移除参数(RoleAssignUsersDto)"
                },
                new
                {
                    Path = "/api/admin/roles/check-name",
                    Method = "GET",
                    Description = "检查角色名是否存在",
                    Parameters = "角色名(string), 排除的角色ID(Guid?)"
                },
                new
                {
                    Path = "/api/admin/roles/{roleId}/permissions",
                    Method = "GET",
                    Description = "获取角色权限 (待实现)",
                    Parameters = "角色ID(Guid)"
                },
                new
                {
                    Path = "/api/admin/roles/assign-permissions",
                    Method = "POST",
                    Description = "为角色分配权限 (待实现)",
                    Parameters = "分配参数(RolePermissionAssignDto)"
                }
            },
            Models = new[]
            {
                new
                {
                    Name = "RoleQueryDto",
                    Properties = new Dictionary<string, string>
                    {
                        { "Name", "角色名称 (string)" },
                        { "IsSystem", "是否系统角色 (bool?)" },
                        { "PageIndex", "页码 (int)" },
                        { "PageSize", "每页记录数 (int)" }
                    }
                },
                new
                {
                    Name = "RoleCreateDto",
                    Properties = new Dictionary<string, string>
                    {
                        { "Name", "角色名称 (string)" },
                        { "Description", "描述 (string)" },
                        { "IsSystem", "是否系统角色 (bool)" }
                    }
                },
                new
                {
                    Name = "RoleUpdateDto",
                    Properties = new Dictionary<string, string>
                    {
                        { "Id", "角色ID (Guid)" },
                        { "Name", "角色名称 (string)" },
                        { "Description", "描述 (string)" },
                        { "ConcurrencyStamp", "并发标记 (string)" }
                    }
                },
                new
                {
                    Name = "RoleItemDto",
                    Properties = new Dictionary<string, string>
                    {
                        { "Id", "角色ID (Guid)" },
                        { "Name", "角色名称 (string)" },
                        { "Description", "描述 (string)" },
                        { "IsSystem", "是否系统角色 (bool)" },
                        { "CreatedTime", "创建时间 (DateTime)" }
                    }
                },
                new
                {
                    Name = "RoleAssignUsersDto",
                    Properties = new Dictionary<string, string>
                    {
                        { "RoleId", "角色ID (Guid)" },
                        { "UserIds", "用户ID列表 (List<Guid>)" }
                    }
                },
                new
                {
                    Name = "RoleBatchDeleteDto",
                    Properties = new Dictionary<string, string>
                    {
                        { "RoleIds", "角色ID列表 (List<Guid>)" }
                    }
                }
            }
        };

        return Ok(docs);
    }

    #region 角色查询

    /// <summary>
    /// 分页查询角色
    /// </summary>
    /// <param name="query">查询条件</param>
    /// <returns>分页结果</returns>
    /// <response code="200">查询成功</response>
    /// <response code="400">请求参数无效</response>
    /// <response code="401">未授权</response>
    [HttpGet]
    [ProducesResponseType(typeof(ApiResponse<PagedList<RoleItemDto>>), 200)]
    [ProducesResponseType(typeof(ApiResponse), 400)]
    [ProducesResponseType(typeof(ApiResponse), 401)]
    public async Task<IActionResult> GetRoles([FromQuery] RoleQueryDto query)
    {
        var result = await _roleService.GetPagedRolesAsync(query);
        return Ok(result);
    }

    /// <summary>
    /// 获取角色详情
    /// </summary>
    /// <param name="id">角色ID</param>
    /// <returns>角色详情</returns>
    /// <response code="200">获取成功</response>
    /// <response code="404">角色不存在</response>
    /// <response code="401">未授权</response>
    [HttpGet("{id}")]
    [ProducesResponseType(typeof(ApiResponse<RoleDetailDto>), 200)]
    [ProducesResponseType(typeof(ApiResponse), 404)]
    [ProducesResponseType(typeof(ApiResponse), 401)]
    public async Task<IActionResult> GetRoleById(Guid id)
    {
        var result = await _roleService.GetRoleDetailAsync(id);
        if (result.IsSuccess)
        {
            return Ok(result);
        }

        if (result.Code == SecurityErrorCodes.ROLE_NOT_FOUND)
        {
            return NotFound(ApiResponse.Error(SecurityErrorCodes.ROLE_NOT_FOUND));
        }

        return BadRequest(result);
    }

    /// <summary>
    /// 获取角色选择列表
    /// </summary>
    /// <returns>角色选择列表</returns>
    /// <response code="200">获取成功</response>
    /// <response code="401">未授权</response>
    [HttpGet("select")]
    [ProducesResponseType(typeof(ApiResponse<List<RoleSelectDto>>), 200)]
    [ProducesResponseType(typeof(ApiResponse), 401)]
    public async Task<IActionResult> GetRoleSelectList()
    {
        var result = await _roleService.GetRoleSelectListAsync();
        return Ok(result);
    }

    #endregion

    #region 角色创建和修改

    /// <summary>
    /// 创建角色
    /// </summary>
    /// <param name="dto">创建信息</param>
    /// <returns>创建结果</returns>
    /// <response code="201">创建成功</response>
    /// <response code="400">请求参数无效</response>
    /// <response code="401">未授权</response>
    /// <response code="409">角色名已存在</response>
    [HttpPost]
    [ProducesResponseType(typeof(ApiResponse<Guid>), 201)]
    [ProducesResponseType(typeof(ApiResponse), 400)]
    [ProducesResponseType(typeof(ApiResponse), 401)]
    [ProducesResponseType(typeof(ApiResponse), 409)]
    public async Task<IActionResult> CreateRole([FromBody] RoleCreateDto dto)
    {
        var result = await _roleService.CreateRoleAsync(dto);
        return Created($"/api/admin/roles/{result.Data}", result);
    }

    /// <summary>
    /// 更新角色
    /// </summary>
    /// <param name="id">角色ID</param>
    /// <param name="dto">更新信息</param>
    /// <returns>更新结果</returns>
    /// <response code="200">更新成功</response>
    /// <response code="400">请求参数无效</response>
    /// <response code="401">未授权</response>
    /// <response code="403">系统角色不允许修改</response>
    /// <response code="404">角色不存在</response>
    /// <response code="409">角色名已存在</response>
    /// <response code="412">数据版本冲突</response>
    [HttpPut("{id}")]
    [ProducesResponseType(typeof(ApiResponse), 200)]
    [ProducesResponseType(typeof(ApiResponse), 400)]
    [ProducesResponseType(typeof(ApiResponse), 401)]
    [ProducesResponseType(typeof(ApiResponse), 403)]
    [ProducesResponseType(typeof(ApiResponse), 404)]
    [ProducesResponseType(typeof(ApiResponse), 409)]
    [ProducesResponseType(typeof(ApiResponse), 412)]
    public async Task<IActionResult> UpdateRole(Guid id, [FromBody] RoleUpdateDto dto)
    {
        if (id != dto.Id)
        {
            return BadRequest(ApiResponse.Error("路径ID与请求体ID不匹配"));
        }

        var result = await _roleService.UpdateRoleAsync(dto);
        return Ok(ApiResponse.Success("角色更新成功"));
    }

    #endregion

    #region 角色删除

    /// <summary>
    /// 删除角色
    /// </summary>
    /// <param name="id">角色ID</param>
    /// <returns>删除结果</returns>
    /// <response code="200">删除成功</response>
    /// <response code="401">未授权</response>
    /// <response code="403">系统角色不允许删除</response>
    /// <response code="404">角色不存在</response>
    [HttpDelete("{id}")]
    [ProducesResponseType(typeof(ApiResponse), 200)]
    [ProducesResponseType(typeof(ApiResponse), 401)]
    [ProducesResponseType(typeof(ApiResponse), 403)]
    [ProducesResponseType(typeof(ApiResponse), 404)]
    public async Task<IActionResult> DeleteRole(Guid id)
    {
        var result = await _roleService.DeleteRoleAsync(id);
        return Ok(ApiResponse.Success("角色删除成功"));
    }

    /// <summary>
    /// 批量删除角色
    /// </summary>
    /// <param name="dto">批量删除参数</param>
    /// <returns>批量删除结果</returns>
    /// <response code="200">删除成功</response>
    /// <response code="400">请求参数无效</response>
    /// <response code="401">未授权</response>
    /// <response code="403">包含系统角色</response>
    [HttpPost("batch-delete")]
    [ProducesResponseType(typeof(ApiResponse<List<Guid>>), 200)]
    [ProducesResponseType(typeof(ApiResponse), 400)]
    [ProducesResponseType(typeof(ApiResponse), 401)]
    [ProducesResponseType(typeof(ApiResponse), 403)]
    public async Task<IActionResult> BatchDeleteRoles([FromBody] RoleBatchDeleteDto dto)
    {
        var result = await _roleService.BatchDeleteRolesAsync(dto);
        return Ok(result);
    }

    #endregion

    #region 角色用户管理

    /// <summary>
    /// 获取角色用户列表
    /// </summary>
    /// <param name="roleId">角色ID</param>
    /// <returns>用户列表</returns>
    /// <response code="200">获取成功</response>
    /// <response code="404">角色不存在</response>
    /// <response code="401">未授权</response>
    [HttpGet("{roleId}/users")]
    [ProducesResponseType(typeof(ApiResponse<IList<User>>), 200)]
    [ProducesResponseType(typeof(ApiResponse), 404)]
    [ProducesResponseType(typeof(ApiResponse), 401)]
    public async Task<IActionResult> GetUsersInRole(Guid roleId)
    {
        var result = await _roleService.GetUsersInRoleAsync(roleId);
        if (result.IsSuccess)
        {
            return Ok(result);
        }

        if (result.Code == SecurityErrorCodes.ROLE_NOT_FOUND)
        {
            return NotFound(ApiResponse.Error(SecurityErrorCodes.ROLE_NOT_FOUND));
        }

        return BadRequest(result);
    }

    /// <summary>
    /// 为角色分配用户
    /// </summary>
    /// <param name="dto">分配参数</param>
    /// <returns>分配结果</returns>
    /// <response code="200">分配成功</response>
    /// <response code="400">请求参数无效</response>
    /// <response code="401">未授权</response>
    /// <response code="404">角色不存在</response>
    [HttpPost("assign-users")]
    [ProducesResponseType(typeof(ApiResponse), 200)]
    [ProducesResponseType(typeof(ApiResponse), 400)]
    [ProducesResponseType(typeof(ApiResponse), 401)]
    [ProducesResponseType(typeof(ApiResponse), 404)]
    public async Task<IActionResult> AssignUsersToRole([FromBody] RoleAssignUsersDto dto)
    {
        var result = await _roleService.AssignUsersToRoleAsync(dto);
        return Ok(ApiResponse.Success("用户分配成功"));
    }

    /// <summary>
    /// 从角色中移除用户
    /// </summary>
    /// <param name="dto">移除参数</param>
    /// <returns>移除结果</returns>
    /// <response code="200">移除成功</response>
    /// <response code="400">请求参数无效</response>
    /// <response code="401">未授权</response>
    /// <response code="404">角色不存在</response>
    [HttpPost("remove-users")]
    [ProducesResponseType(typeof(ApiResponse), 200)]
    [ProducesResponseType(typeof(ApiResponse), 400)]
    [ProducesResponseType(typeof(ApiResponse), 401)]
    [ProducesResponseType(typeof(ApiResponse), 404)]
    public async Task<IActionResult> RemoveUsersFromRole([FromBody] RoleAssignUsersDto dto)
    {
        var result = await _roleService.RemoveUsersFromRoleAsync(dto);
        return Ok(ApiResponse.Success("用户移除成功"));
    }

    #endregion

    #region 角色名检查

    /// <summary>
    /// 检查角色名是否存在
    /// </summary>
    /// <param name="roleName">角色名称</param>
    /// <param name="excludeRoleId">排除的角色ID</param>
    /// <returns>检查结果</returns>
    /// <response code="200">检查成功</response>
    /// <response code="400">请求参数无效</response>
    /// <response code="401">未授权</response>
    [HttpGet("check-name")]
    [ProducesResponseType(typeof(ApiResponse<bool>), 200)]
    [ProducesResponseType(typeof(ApiResponse), 400)]
    [ProducesResponseType(typeof(ApiResponse), 401)]
    public async Task<IActionResult> CheckRoleName([FromQuery] string roleName, [FromQuery] Guid? excludeRoleId = null)
    {
        if (string.IsNullOrWhiteSpace(roleName))
        {
            return BadRequest(ApiResponse.Error("角色名不能为空"));
        }

        var result = await _roleService.IsRoleNameExistsAsync(roleName, excludeRoleId);
        return Ok(result);
    }

    #endregion

    /// <summary>
    /// 获取API接口文档
    /// </summary>
    /// <returns>接口文档</returns>
    [HttpGet("api-doc")]
    [ProducesResponseType(typeof(object), 200)]
    [AllowAnonymous]
    public IActionResult GetApiDoc()
    {
        var docs = new
        {
            ApiName = "角色管理API",
            Version = "1.0",
            Description = "提供角色管理相关功能",
            Endpoints = new object[]
            {
                new
                {
                    Path = "/api/admin/roles",
                    Method = "GET",
                    Description = "分页查询角色列表",
                    Parameters = new Dictionary<string, string>
                    {
                        { "name", "角色名称关键词" },
                        { "isSystem", "是否系统角色" },
                        { "pageIndex", "页码" },
                        { "pageSize", "页大小" }
                    }
                },
                new
                {
                    Path = "/api/admin/roles/{id}",
                    Method = "GET",
                    Description = "获取角色详情",
                    Parameters = new Dictionary<string, string>
                    {
                        { "id", "角色ID" }
                    }
                },
                new
                {
                    Path = "/api/admin/roles",
                    Method = "POST",
                    Description = "创建角色",
                    RequestBody = "RoleCreateDto"
                },
                new
                {
                    Path = "/api/admin/roles/{id}",
                    Method = "PUT",
                    Description = "更新角色",
                    Parameters = new Dictionary<string, string>
                    {
                        { "id", "角色ID" }
                    },
                    RequestBody = "RoleUpdateDto"
                },
                new
                {
                    Path = "/api/admin/roles/{id}",
                    Method = "DELETE",
                    Description = "删除角色",
                    Parameters = new Dictionary<string, string>
                    {
                        { "id", "角色ID" }
                    }
                }
            },
            Models = new object[]
            {
                new
                {
                    Name = "RoleCreateDto",
                    Properties = new Dictionary<string, string>
                    {
                        { "Name", "角色名称 (string)" },
                        { "Description", "描述 (string)" }
                    }
                },
                new
                {
                    Name = "RoleUpdateDto",
                    Properties = new Dictionary<string, string>
                    {
                        { "Id", "角色ID (Guid)" },
                        { "Name", "角色名称 (string)" },
                        { "Description", "描述 (string)" },
                        { "ConcurrencyStamp", "并发标记 (string)" }
                    }
                },
                new
                {
                    Name = "RoleItemDto",
                    Properties = new Dictionary<string, string>
                    {
                        { "Id", "角色ID (Guid)" },
                        { "Name", "角色名称 (string)" },
                        { "Description", "描述 (string)" },
                        { "IsSystem", "是否系统角色 (bool)" },
                        { "CreatedTime", "创建时间 (DateTime)" }
                    }
                },
                new
                {
                    Name = "RoleAssignUsersDto",
                    Properties = new Dictionary<string, string>
                    {
                        { "RoleId", "角色ID (Guid)" },
                        { "UserIds", "用户ID列表 (List<Guid>)" }
                    }
                },
                new
                {
                    Name = "RoleBatchDeleteDto",
                    Properties = new Dictionary<string, string>
                    {
                        { "RoleIds", "角色ID列表 (List<Guid>)" }
                    }
                }
            }
        };

        return Ok(docs);
    }
}